#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# ======================================================
# @File:      : base_bp
# @Author     : forward_huan
# @Date       : 2025/5/28 18:04
# @Desc       :
# ======================================================
import json
import os
import shutil
import time

from flask import Blueprint, render_template, request
from werkzeug.datastructures import FileStorage

from common.utils.data_utils import to_int
from common.utils.file_utils import modifyFileTime
from common.utils.path_utils import pathJoin, removeFileOrDir
from common.utils.time_utils import toDatetimeFromMS, getDatetimeStr
from upload_file.model.file_model import FileModel
from upload_file.utils.path_utils import get_cache_path
from upload_file.utils.utils import get_url_address

base_bp = Blueprint("base", __name__, "/")


@base_bp.route("/", methods=["GET"])
def index():
    return render_template("index.html", base_url=get_url_address())


def save_file_server(file: FileStorage, save_path, content_range: str):
    """
    保存文件

    :param file: 文件数据
    :param save_path: 保存路径
    :param content_range: bytes start-end/total (包含end), 如: 'bytes 0-6616/6617'
    :return:
    """
    if isinstance(content_range, str):
        content_range = content_range.replace("bytes", "").replace("/", "-").strip()
        start, end, total = map(lambda x: int(x.strip()), content_range.split("-"))
        with open(save_path, "ab") as f:
            f.seek(start)
            f.write(file.read())
        return (end + 1) == total
    file.save(save_path)
    return True


def get_save_path(info: str):
    file_info: dict = json.loads(info)
    # 文件修改时间是毫秒(ms)
    m_time = to_int(file_info.get("mtime", time.time() * 1000))
    dtime = toDatetimeFromMS(m_time)
    save_dir = get_cache_path("file", getDatetimeStr(dtime, "%Y%m"), is_dir=True)
    name, ext = os.path.splitext(file_info.get("name", ""))
    save_path = pathJoin(save_dir, "{}{}".format(getDatetimeStr(dtime, fmt="%Y%m%d_%H%M%S_%f")[:-3], ext))
    return m_time, save_path


@base_bp.route("/check_exist", methods=["POST"])
def check_exist():
    """检查文件是否已经上传"""
    args = request.form
    # 文件修改时间是毫秒(ms)
    m_time, save_path = get_save_path(args.get("info", "{}"))
    file_model = FileModel({"file_time": m_time, "save_path": save_path, "state": 1})
    return {"msg": file_model.exist(["file_time"])}


@base_bp.route("/upload_file", methods=["GET", "POST"])
def upload_file():
    form, files = dict(request.form), request.files
    file = files.get("file")
    if not file:
        raise Exception("未发现文件数据")
    m_time, save_path = get_save_path(form.get("info", "{}"))
    temp_path = "{}_temp".format(save_path)
    is_all = save_file_server(file, temp_path, request.headers.get("Content-Range"))
    if not is_all:
        return {"msg": "文件上传中"}
    removeFileOrDir(save_path)
    shutil.move(temp_path, save_path)
    modifyFileTime(save_path, mtime=m_time, ctime=m_time)
    file_model = FileModel({"file_time": m_time, "save_path": save_path, "state": 1})
    file_model.save()
    return {"msg": "文件上传成功"}
